package com.shop.shoppingmall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shop.shoppingmall.dao.ShBackUserDao;
import com.shop.shoppingmall.dao.ShUserDao;
import com.shop.shoppingmall.entity.CountSum;
import com.shop.shoppingmall.entity.ShBackUser;
import com.shop.shoppingmall.entity.ShOrder;
import com.shop.shoppingmall.entity.ShUser;
import com.shop.shoppingmall.util.*;
import com.shop.shoppingmall.util.api.vo.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.shop.shoppingmall.service.ShBackUserService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * (ShBackUser)表服务实现类
 *
 * @author makejava
 * @since 2020-09-16 16:45:20
 */
@Service("shBackUserService")
@Transactional
public class ShBackUserServiceImpl implements ShBackUserService {
    @Resource
    private ShBackUserDao shBackUserDao;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ShUserDao shUserDao;

    /**
     * 通过ID查询单条数据
     *
     * @param userId 主键
     * @return 实例对象
     */
    @Override
    public ShBackUser queryById(String userId) {
        return this.shBackUserDao.queryById(userId);
    }

    /**
     * 新增数据
     *
     * @param shBackUser 实例对象
     * @return 实例对象
     */
    @Override
    public ShBackUser insert(ShBackUser shBackUser) {
        this.shBackUserDao.insert(shBackUser);
        return shBackUser;
    }

    /**
     * 修改数据
     *
     * @param shBackUser 实例对象
     * @return 实例对象
     */
    @Override
    public ShBackUser update(ShBackUser shBackUser) {
        this.shBackUserDao.update(shBackUser);
        return this.queryById(shBackUser.getUserId());
    }

    /**
     * 通过主键删除数据
     *
     * @param userId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String userId) {
        return this.shBackUserDao.deleteById(userId) > 0;
    }

    /**
     * 后台用户注册
     * @param jsonObject
     * @return
     */
    @Override
    public Result backRegister(JSONObject jsonObject) {
        ShBackUser shBackUser = JSON.parseObject(jsonObject.toJSONString(), ShBackUser.class);
        if(shBackUser.getLoginName() == null || shBackUser.getLoginPassword() == null){
            return Result.error(CommonConstant.SC_INTERNAL_SERVER_ERROR_502,"账号或者密码不能为空");
        }
        if(shBackUserDao.selectLoginName(shBackUser.getLoginName()) != null){
            return Result.error(CommonConstant.SC_INTERNAL_SERVER_ERROR_501,"该账号已经被注册");
        }
        String userId = UUIDGenerator.generate();
        shBackUser.setUserId(userId);
        String salt = oConvertUtils.randomGen(8);
        shBackUser.setSalt(salt);
        String passwordEncode = PasswordUtil.encrypt(userId, shBackUser.getLoginPassword(), salt);
        shBackUser.setLoginPassword(passwordEncode);

        shBackUserDao.insert(shBackUser);
        return Result.ok("注册成功");
    }


    //判断用户状态ok
    @Override
    public Result<?> checkUserIsEffective(ShBackUser shBackUser) {
        Result<?> result = new Result<Object>();
        //情况1：根据用户信息查询，该用户不存在
        if (shBackUser == null) {
            result.error500("该用户不存在，请注册");
            return result;
        }
        //情况2：根据用户信息查询，该用户已冻结
        if (CommonConstant.USER_FREEZE.equals(shBackUser.getStatus())) {
            result.error500("该用户已停用");
            return result;
        }
        return result;
    }

    /**
     * 用户登录
     * @param map
     * @return
     */
    @Override
    public Result userLogin(Map map) {
        Result<JSONObject> result = new Result<JSONObject>();
        String loginName = (String) map.get("loginName");
        String loginPassword = (String) map.get("loginPassword");

        //检验用户是否有效
        ShBackUser shBackUser = shBackUserDao.selectLoginName(loginName);
        result = (Result<JSONObject>) checkUserIsEffective(shBackUser);
        if(!result.isSuccess()) {
            return result;
        }
        String password = PasswordUtil.encrypt(shBackUser.getUserId(), loginPassword, shBackUser.getSalt());
        String backUserLoginPassword = shBackUser.getLoginPassword();
        if (!password.equals(backUserLoginPassword)) {
            result.error500("用户名或密码错误");
            return result;
        }
        JSONObject obj = new JSONObject();
        //用户登录信息
        obj.put("backUserInfo", shBackUser);
        // 生成token
        String token = JwtUtil.sign(loginName, backUserLoginPassword);
        // 设置超时时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
        //token 信息
        obj.put("token", token);
        result.setResult(obj);
        result.setSuccess(true);
        result.setCode(200);
        return result;
    }

    /**
     * 查询首页的所有信息
     * @return
     */
    @Override
    public Result selectHomeAll() {
        HashMap<String, Object> map = new HashMap<>();
        //查询APP登录的所有用户信息
        ShUser shUser = shUserDao.selectAll();
        Integer statusCount = shUser.getStatusCount();

        //查询所有注册过的用户的数量
        ShUser shUsers = shUserDao.selectUserAll();
        Integer userCount = shUsers.getUserCount();
        map.put("statusCount",statusCount);
        map.put("userCount",userCount);
        return Result.ok(map);
    }

    /**
     * 后台用户修改个人信息
     * @param shBackUser
     * @return
     */
    @Override
    public Result updateShUserByUserId(ShBackUser shBackUser) {
        shBackUserDao.update(shBackUser);
        return Result.ok("成功修改个人信息");

    }

    /**
     * 后台查询所有用户的信息
     * @param map
     * @return
     */
    @Override
    public Result selectQueryAll(Map map) {
        Integer pagenum = (Integer) map.get("pagenum");
        Integer pagesize = (Integer) map.get("pagesize");
        int a = (pagenum-1)*pagesize;
        map.put("offset",a);
        map.put("limit",pagesize);
        List<ShBackUser> shBackUsers = shBackUserDao.queryAll(map);
        if(shBackUsers.isEmpty()){
            return Result.error("暂时还没有后台用户信息！");
        }
        ShBackUser shBackUser = shBackUserDao.querySumCount();
        Map map1 = new HashMap();
        map1.put("total", shBackUser.getTotal());
        map1.put("shBackUsers",shBackUsers);
        return Result.ok(map1);
    }

    /**
     * 修改密码
     * @param
     * @param oldpassword 旧密码
     * @param newpassword 新密码
     * @param confirmpassword 确认密码
     * @return
     */
    @Override
    public Result resetPassword(HttpServletRequest request, String oldpassword, String newpassword, String confirmpassword) {
        String name = JwtUtil.getUserNameByToken(request);
        ShBackUser shBackUser = shBackUserDao.selectLoginName(name);
        if (shBackUser == null || name == null) {
            return Result.error(CommonConstant.SC_OK_201,"您还未注册或者登录，请先注册或登录");
        }
        String phone = shBackUser.getPhone();
        String passwordEncode = PasswordUtil.encrypt(shBackUser.getUserId(), oldpassword, shBackUser.getSalt());
        if (!shBackUser.getLoginPassword().equals(passwordEncode)) {
            return Result.error("旧密码输入错误!");
        }
        if (oConvertUtils.isEmpty(newpassword)) {
            return Result.error("新密码不允许为空!");
        }
        if (!newpassword.equals(confirmpassword)) {
            return Result.error("两次输入密码不一致!");
        }
        String password = PasswordUtil.encrypt(shBackUser.getUserId(), newpassword, shBackUser.getSalt());
        shBackUser.setLoginPassword(password);
        shBackUserDao.update(shBackUser);
        return Result.ok("密码修改成功！");
    }

    /**
     * 重置密码
     * @param
     * @param smscode
     * @param password
     * @return
     */
    @Override
    public Result chongZhiPassword(String phone,String loginName, String smscode, String password) {
        ShBackUser shBackUser = shBackUserDao.selectAllByPhone(phone,loginName);
        if(shBackUser == null){
            return Result.error("账号不存在");
        }
        Object code = redisUtil.get(shBackUser.getPhone());
        if (!smscode.equals(code)) {
            return Result.error("手机验证码错误");
        }
        String resetPassword = PasswordUtil.encrypt(shBackUser.getUserId(), password, shBackUser.getSalt());
        shBackUser.setLoginPassword(resetPassword);
        shBackUserDao.update(shBackUser);
        return Result.ok("密码重置成功！");
    }

    /**
     * 用于数据回显
     * @param userId
     * @return
     */
    @Override
    public Result selectByUserId(String userId) {
        ShBackUser shBackUser = shBackUserDao.selectByUserId(userId);
        if(shBackUser == null){
            return Result.error("还没有该用户的信息！");
        }
        return Result.ok(shBackUser);
    }

    @Override
    public Result queryCount(String merchantId) {
        if(merchantId == null || merchantId.equals("")){
            CountSum countSum = shBackUserDao.queryCount();
            return Result.ok(countSum);
        }else{
            CountSum countSum = shBackUserDao.queryCount1(merchantId);
            return Result.ok(countSum);
        }
    }
    @Override
    public Result selectOrderS(String merchantId) {
        if(merchantId == null || merchantId.equals("")){
            CountSum countSum = shBackUserDao.selectOrderS1();
            if(countSum !=null){
                BigDecimal a1 = new BigDecimal(countSum.getPayMentOther()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a2 = new BigDecimal(countSum.getConsignment()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a3 = new BigDecimal(countSum.getDelivered()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a4 = new BigDecimal(countSum.getCompleted()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a5= new BigDecimal(countSum.getCancel()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                countSum.setPayMentOther(Integer.valueOf(a1.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setConsignment(Integer.valueOf(a2.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setDelivered(Integer.valueOf(a3.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setCompleted(Integer.valueOf(a4.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setCancel(Integer.valueOf(a5.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
            }
            return Result.ok(countSum);
        }else{
            CountSum countSum = shBackUserDao.selectOrderS(merchantId);
            if(countSum !=null){
                BigDecimal a1 = new BigDecimal(countSum.getPayMentOther()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a2 = new BigDecimal(countSum.getConsignment()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a3 = new BigDecimal(countSum.getDelivered()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a4 = new BigDecimal(countSum.getCompleted()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                BigDecimal a5= new BigDecimal(countSum.getCancel()).divide(new BigDecimal(countSum.getTotalCount()),2, BigDecimal.ROUND_HALF_UP);
                countSum.setPayMentOther(Integer.valueOf(a1.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setConsignment(Integer.valueOf(a2.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setDelivered(Integer.valueOf(a3.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setCompleted(Integer.valueOf(a4.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
                countSum.setCancel(Integer.valueOf(a5.multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP).toString()));
            }
            return Result.ok(countSum);
        }
    }
}
